/*
 * main.c
 *
 *  Created on: Nov 27, 2010
 *      Author: cumeo89
 */

#include <glib.h>
#include <gmodule.h>
#include <gtk/gtk.h>
#include <glib/gstdio.h>
#include <stdlib.h>
#include "gui.h"
#include "visual.h"
#include "suffixtree.h"
#include "lcstr.h"

GtkWindow *window;
GtkImage *treeImg;
GtkButton *computeBtn;
GtkButton *firstBtn;
GtkButton *previousBtn;
GtkButton *nextBtn;
GtkButton *lastBtn;
GtkEntry *dotTxt;
GtkEntry *s1Txt;
GtkEntry *s2Txt;
GtkEntry *s3Txt;
GtkEntry *s4Txt;
GtkEntry *s5Txt;
GPtrArray *lcstrTxts;
GtkEntry *image_count_txt;
GtkEntry *image_index_txt;
GtkButton *aboutBtn;
GtkAboutDialog *aboutDlg;

VisualizerData data;
int currentIndex;
SuffixTree *tree;
CommonString *cs;

G_MODULE_EXPORT void on_window_destroy(GtkObject *object, gpointer user_data) {
	gtk_main_quit();
}

void add_string(GtkEntry *entry, const gchar **strings, int *n) {
	if (gtk_entry_get_text_length(entry) > 0) {
		strings[*n] = gtk_entry_get_text(entry); // don't need to free them
		++ *n;
	}
}

int get_strings(const gchar **strings) {
	int n = 0;
	add_string(s1Txt, strings, &n);
	add_string(s2Txt, strings, &n);
	add_string(s3Txt, strings, &n);
	add_string(s4Txt, strings, &n);
	add_string(s5Txt, strings, &n);
	strings[n] = NULL;
	return n;
}

void set_current_index(int index) {
	if (index < 0 || index >= data.counter) {
		printf("Invalid index: %d.", index);
		return;
	}

	currentIndex = index;
	gtk_widget_set_sensitive(GTK_WIDGET(firstBtn), currentIndex > 0);
	gtk_widget_set_sensitive(GTK_WIDGET(previousBtn), currentIndex > 0);
	gtk_widget_set_sensitive(GTK_WIDGET(lastBtn), currentIndex < data.counter-1);
	gtk_widget_set_sensitive(GTK_WIDGET(nextBtn), currentIndex < data.counter-1);

	gchar buffer[4];
	snprintf(buffer, 4, "%d", currentIndex+1);
	gtk_entry_set_text(image_index_txt, buffer);
	snprintf(buffer, 4, "%d", data.counter);
	gtk_entry_set_text(image_count_txt, buffer);

	gchar path[1024];
	get_image_path(path, &data, currentIndex);
	gtk_image_set_from_file(treeImg, path);
}

void set_entries_enabled(gboolean locked) {
	gtk_widget_set_sensitive(GTK_WIDGET(s1Txt), !locked);
	gtk_widget_set_sensitive(GTK_WIDGET(s2Txt), !locked);
	gtk_widget_set_sensitive(GTK_WIDGET(s3Txt), !locked);
	gtk_widget_set_sensitive(GTK_WIDGET(s4Txt), !locked);
	gtk_widget_set_sensitive(GTK_WIDGET(s5Txt), !locked);
}

void set_buttons_enabled(gboolean enabled) {
	gtk_widget_set_sensitive(GTK_WIDGET(firstBtn), enabled);
	gtk_widget_set_sensitive(GTK_WIDGET(previousBtn), enabled);
	gtk_widget_set_sensitive(GTK_WIDGET(nextBtn), enabled);
	gtk_widget_set_sensitive(GTK_WIDGET(lastBtn), enabled);
	gtk_widget_set_sensitive(GTK_WIDGET(image_count_txt), enabled);
	gtk_widget_set_sensitive(GTK_WIDGET(image_index_txt), enabled);
}

void clear_lcstr_texts() {
	int i;
	for (i = 0; i < lcstrTxts->len; i++) {
		if (g_ptr_array_index(lcstrTxts, i) != NULL) {
			GtkEntry *txt = GTK_ENTRY(g_ptr_array_index(lcstrTxts, i));
			gtk_entry_set_text(txt, "");
		}
	}
}

G_MODULE_EXPORT void on_computeBtn_clicked(GtkButton *button, gpointer user_data) {
	data.counter = 0;
	const gchar *strings[6];
	int K = get_strings(strings);
	data.dot = gtk_entry_get_text(dotTxt);
	tree = t_new_callback(strings, visualize, &data);
	cs = find_lcstr_tree(strings, tree);

	clear_lcstr_texts();
	int i;
	for (i = 0; i < K-1; i++) {
		GtkEntry *lcstrTxt = GTK_ENTRY (g_ptr_array_index(lcstrTxts, i));
		gtk_entry_set_text(lcstrTxt, cs_get_substring(&cs[i]));
	}

	set_buttons_enabled(TRUE);
	set_current_index(data.counter-1);
}

G_MODULE_EXPORT void on_firstBtn_clicked(GtkButton *button, gpointer user_data) {
	set_current_index(0);
}

G_MODULE_EXPORT void on_previousBtn_clicked(GtkButton *button, gpointer user_data) {
	if (currentIndex > 0) {
		set_current_index(currentIndex-1);
	}
}

G_MODULE_EXPORT void on_nextBtn_clicked(GtkButton *button, gpointer user_data) {
	if (currentIndex < data.counter-1) {
		set_current_index(currentIndex+1);
	}
}

G_MODULE_EXPORT void on_lastBtn_clicked(GtkButton *button, gpointer user_data) {
	set_current_index(data.counter-1);
}

G_MODULE_EXPORT void on_index_entered() {
	long v = strtol(gtk_entry_get_text(image_index_txt), NULL, 10);
	if (v > 0 && v <= data.counter) {
		set_current_index(v-1);
	}
}

G_MODULE_EXPORT void on_image_index_txt_activate(GtkEntry *entry, gpointer  user_data) {
	on_index_entered();
}

G_MODULE_EXPORT void on_image_index_txt_focus_out_event(GtkWidget *entry, gpointer  user_data) {
	on_index_entered();
}

G_MODULE_EXPORT void on_aboutBtn_clicked(GtkButton *button, gpointer user_data) {
	gtk_widget_show(GTK_WIDGET(aboutDlg));
}

int gui_run() {
	data.edgeLabelType = EDGE_LABEL_TYPE_SUBSTRING;
	data.dir = g_build_path(G_DIR_SEPARATOR_S, g_get_tmp_dir(), "cs-suffix-tree", NULL);
	g_mkdir(data.dir, 0777);

	GtkBuilder *builder;

	gtk_init(NULL, NULL);

	builder = gtk_builder_new();
	gtk_builder_add_from_file(builder, "ui.glade", NULL);

	window = GTK_WINDOW (gtk_builder_get_object (builder, "window"));
	treeImg = GTK_IMAGE (gtk_builder_get_object (builder, "treeImg"));
	computeBtn = GTK_BUTTON (gtk_builder_get_object (builder, "computeBtn"));
	firstBtn = GTK_BUTTON (gtk_builder_get_object (builder, "firstBtn"));
	previousBtn = GTK_BUTTON (gtk_builder_get_object (builder, "previousBtn"));
	nextBtn = GTK_BUTTON (gtk_builder_get_object (builder, "nextBtn"));
	lastBtn = GTK_BUTTON (gtk_builder_get_object (builder, "lastBtn"));
	s1Txt = GTK_ENTRY (gtk_builder_get_object(builder, "s1"));
	s2Txt = GTK_ENTRY (gtk_builder_get_object(builder, "s2"));
	s3Txt = GTK_ENTRY (gtk_builder_get_object(builder, "s3"));
	s4Txt = GTK_ENTRY (gtk_builder_get_object(builder, "s4"));
	s5Txt = GTK_ENTRY (gtk_builder_get_object(builder, "s5"));
	lcstrTxts = g_ptr_array_new();
	g_ptr_array_add(lcstrTxts, gtk_builder_get_object(builder, "lcstrTxt2"));
	g_ptr_array_add(lcstrTxts, gtk_builder_get_object(builder, "lcstrTxt3"));
	g_ptr_array_add(lcstrTxts, gtk_builder_get_object(builder, "lcstrTxt4"));
	g_ptr_array_add(lcstrTxts, gtk_builder_get_object(builder, "lcstrTxt5"));
	image_count_txt = GTK_ENTRY(gtk_builder_get_object(builder, "image_count_txt"));
	image_index_txt = GTK_ENTRY(gtk_builder_get_object(builder, "image_index_txt"));
	dotTxt = GTK_ENTRY(gtk_builder_get_object(builder, "dotTxt"));
	aboutBtn = GTK_BUTTON(gtk_builder_get_object(builder, "aboutBtn"));
	aboutDlg = GTK_ABOUT_DIALOG(gtk_builder_get_object(builder, "aboutDlg"));

	gtk_builder_connect_signals(builder, NULL);
	g_object_unref(G_OBJECT (builder));

	gtk_window_set_default(window, GTK_WIDGET(computeBtn));
	gtk_widget_show(GTK_WIDGET(window));
	gtk_main();

	g_ptr_array_free(lcstrTxts, FALSE);

	return 0;
}
